#! /usr/bin/env python
# -*- coding: utf-8 -*-

# *************************************************************
#     Filename @  ponitor.py
#       Author @  Huoty
#  Create date @  2016-07-08 16:09:03
#  Description @  process monitor
# *************************************************************

from __future__ import absolute_import, print_function, division

import os
import sys
from argparse import ArgumentParser

import logging
logging.basicConfig(level=logging.INFO,
        format='%(asctime)s %(levelname)s %(message)s')

log = logging

sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
from pps import processes, mem_percent, cpu_percent


def monitor(mem_limit=60, cpu_limit=90, ignore=None):
    """Watch all processes in the system

    If you exceed limit was killed
    """
    ignore = ignore if ignore else []
    for p in processes():
        for pname in ignore:
            if pname in p.cmd:
                continue

        try:
            p.update()
            total_mem_percent = mem_percent()
            total_cpu_percent = cpu_percent()

            condition1 = p.mem > mem_limit and total_mem_percent > 90
            condition2 = p.cpu > cpu_limit and total_cpu_percent > 90

            if condition1 or condition2:
                p.kill()
                log.info("kill: %s, mem: %s, cpu: %s" % (repr(p), p.mem, p.cpu))
        except Exception as err:
            log.error(err)


# Script starts from here

if __name__ == "__main__":
    parser = ArgumentParser(prog="ponitor",
                        description="Watch all processes in the system",
                        epilog="Example: ponitor --interval=5 --ignore=atom,terminator")
    parser.add_argument("--interval",
                        type=int,
                        default=5,
                        help="How long interval run once")
    parser.add_argument("--mem-limit",
                        type=int,
                        default=60,
                        help="CPU limit")
    parser.add_argument("--cpu-limit",
                        type=int,
                        default=90,
                        help="Memory limit")
    parser.add_argument("--ignore",
                        type=str,
                        default=None,
                        help="Ignore some proces")
    parser.add_argument("--logfile",
                        type=str,
                        default="/tmp/ponitor.log",
                        help="log file of daemon mode")
    parser.add_argument("-d", "--daemon",
                        type=str,
                        default=None,
                        choices=["start", "stop", "restart", "status"],
                        help="Daemon mode")

    options = parser.parse_args()
    ignore_list = options.ignore.split(",") if options.ignore else []

    from apscheduler.schedulers.background import BlockingScheduler
    sched = BlockingScheduler()
    sched.add_job(monitor, 'interval', seconds=options.interval, args=(options.mem_limit, \
        options.cpu_limit, ignore_list))

    if options.daemon:
        daemon = Daemon(pidfile, target=sched.start, logfile=options.logfile)

        {
            'start':   daemon.start,
            'stop':    daemon.stop,
            'restart': daemon.restart,
            'status':  daemon.status,
        }.get(options.daemon, lambda: None)()
    else:
        sched.start()
